/*
 * Copyright (c) 2022 Hong Jiahua
 * https://gitee.com/arrco/jh_flowing_deque
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
#include <stdio.h>

#include "jh_flowing_deque.h"
/************************************************************************/
/*                                                                      */
/************************************************************************/
typedef struct {
    int sum;
    int count;
} my_struct_t;

void my_handle(void* in, void* out, void* user_data) {
    int myin = 0, myout = 0;
    my_struct_t* mydata = (my_struct_t*)user_data;
    
    //获取入队的数据
    if(in) {
        myin = *(int *)in;
        mydata->count += 1;
    }
    
    //获取出队的数据
    if(out) {
        myout = *(int *)out;
        mydata->count -= 1;
    }
    
    //计算数据和
    mydata->sum -= myout;
    mydata->sum += myin;
    
    //打印结果
    if(mydata->count)
        printf("sum %d count %d average val %d\n", mydata->sum, mydata->count, mydata->sum / mydata->count);
    else
        printf("sum %d count %d\n", mydata->sum, mydata->count);
}

int main(int argc, char* argv[])
{
    //定义数据结构和用于存放数据的数组
    jh_flowing_deque_t deque;
    int buf[4];
    
    //定义用户自定义数据结构
    my_struct_t mydata = {0};
    
    //双端队列初始化，可用于入队的数据数量为3
    jh_flowing_deque_init(&deque, buf, 3 + 1, sizeof(int), &mydata, my_handle);
    
    //定义要用于传入的数据
    int items[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    int i, val;
    int len;
    
    //数据添加到队尾
    printf("\npush tail:\n");
    for(i = 0; i < sizeof(items)/sizeof(int); i++) {
        printf("push data %d\n", items[i]);
        jh_flowing_deque_push_tail(&deque, &items[i]);
    }
    printf("\n");
    
    //查看当前的状态
    printf("\nsize : %d empty : %d full : %d\n", jh_flowing_deque_count(&deque), jh_flowing_deque_is_empty(&deque), jh_flowing_deque_is_full(&deque));
     
    //查看队首的数据
    jh_flowing_deque_peek_head(&deque, &val);
    printf("\npeek head %d\n", val);
    
    //查看队尾的数据
    jh_flowing_deque_peek_tail(&deque, &val);
    printf("\npeek tail %d\n", val);
    
    //队首数据出队
    len = jh_flowing_deque_count(&deque);
    printf("\npop head:\n");
    for(i = 0; i < len; i++) {
        if(!jh_flowing_deque_pop_head(&deque, &val))
            printf("pop data %d\n", val);
    }
    printf("\n");
    
    //查看当前的状态
    printf("\nsize : %d empty : %d full : %d\n", jh_flowing_deque_count(&deque), jh_flowing_deque_is_empty(&deque), jh_flowing_deque_is_full(&deque));
    
    //数据添加到队首
    printf("\npush head:\n");
    for(i = 0; i < sizeof(items)/sizeof(int); i++) {
        printf("push data %d\n", items[i]);
        jh_flowing_deque_push_head(&deque, &items[i]);
    }
    printf("\n");

    //将队尾数据出队
    len = jh_flowing_deque_count(&deque);
    printf("\npop tail:\n");
    for(i = 0; i < len; i++) {
        if(!jh_flowing_deque_pop_tail(&deque, &val))
            printf("pop data %d\n", val);
    }
    printf("\n");
    
    return 0;
}